﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Semantics.Silverlight;
namespace SilverlightParser
{
    public partial class CategoryControl : TreeView
    {
        public CategoryControl()
        {
            InitializeComponent();
        }
        public bool DesignMode { get; set; }
        RemotableMentorProxy Mentor;
        Window Owner
        {
            get
            {
                object parent = this.Parent;
                while (!(parent is Window))
                    parent = ((Control)parent).Parent;
                return (Window)parent;
            }
        }

        Dictionary<int, TreeViewItem> CategoryTreeNodes = new Dictionary<int, TreeViewItem>();
        public void ShowRootCategory(RemotableMentorProxy mentor)
        {
            this.Mentor = mentor;
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                try
                {
                    List<Category> rootcategories = this.Mentor.GetSubCategories(-1);
                    this.Dispatcher.BeginInvoke(delegate
                    {
                        this.ShowRootCategories(rootcategories);
                    });
                }
                catch (Exception exp)
                {
                    this.OnException(exp);
                }
            });
        }

        void OnException(Exception exp)
        {
            if (this.Dispatcher.CheckAccess())
            {
                this.ShowError(exp.ToString());
            }
            else
                this.Dispatcher.BeginInvoke(delegate
                {
                    this.ShowError(exp.ToString());
                });
        }

        void ShowError(string error)
        {
            MessageBox.Show(error);
        }
        void ShowRootCategories(List<Category> rootcategories)
        {
            if (rootcategories == null)
                return;
            foreach (Category category in rootcategories)
            {
                if (this.SelectedTreeViewItem == null)
                    ShowCategory(category, this.Items);
                else
                {
                    ShowCategory(category, this.SelectedTreeViewItem.Items);
                    this.SelectedTreeViewItem.IsEnabled = true;
                }
            }
        }

        void ShowSubCategories(List<Category> subcategories, TreeViewItem parentitem)
        {
            foreach (Category category in subcategories)
                ShowCategory(category, parentitem.Items);
            parentitem.IsExpanded = true;
        }
        TreeViewItem ShowCategory(Category category, ItemCollection nodes)
        {
            TreeViewItem treenode = new TreeViewItem();
            treenode.Header = category.ToString();
            treenode.Tag = category;
            nodes.Add(treenode);
            this.CategoryTreeNodes.Add(category.NodeId, treenode);
            return treenode;
        }

        private void CategoryControl_NodeMouseClick(object sender, TreeViewItem item)
        {
            try
            {
                Category category = (Category)item.Tag;
                if (item.Items.Count == 0 && !category.IsMargin)
                {//展开
                    System.Threading.ThreadPool.QueueUserWorkItem(delegate{
                        List<Category> subcats = this.Mentor.GetSubCategories(category.NodeId);
                        this.Dispatcher.BeginInvoke(delegate{
                            this.ShowSubCategories(subcats, item);
                        });
                    });
                    /*
                    for (int i = 0; i < subcats.Count; i++)
                    {
                        Category subcategory = (Category)subcats[i];
                        this.ShowCategory(subcategory, item.Items);
                        item.IsExpanded = true;
                    }*/
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(this.Owner, exp.ToString());
            }
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.DesignMode)
                return;
            if (this.Mentor == null)
                return;//in design mode
            this.Mentor.GetCategroyHierarchyCompletedEvent += new RemotableMentorProxy.GetCategroyHierarchyCompletedEventDelegate(Mentor_GetCategroyHierarchyCompletedEvent);
        }


        public delegate void CategoryEventHandler(Category category);
        public event CategoryEventHandler SelectedCategoryChanged;
        public TreeViewItem SelectedTreeViewItem;
        public Category SelectedCategory;
        private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            try
            {
                if (this.SelectedItem == null)
                    return;
                this.SelectedTreeViewItem = (TreeViewItem)this.SelectedItem;
                this.SelectedCategory = (Category)this.SelectedTreeViewItem.Tag;
                if (this.SelectedTreeViewItem.Items.Count == 0 && !this.SelectedCategory.IsMargin)
                {//展开
                    System.Threading.ThreadPool.QueueUserWorkItem(delegate
                    {
                        try
                        {
                            List<Category> subcats = this.Mentor.GetSubCategories(this.SelectedCategory.NodeId);
                            this.Dispatcher.BeginInvoke(delegate
                            {
                                this.ShowSubCategories(subcats, this.SelectedTreeViewItem);
                            });
                        }
                        catch (Exception exp)
                        {
                            this.Dispatcher.BeginInvoke(delegate
                            {
                                this.OnException(exp);
                            });
                        }
                    });
                }
                if (this.SelectedCategoryChanged != null)
                    this.SelectedCategoryChanged(this.SelectedCategory);
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
        }
        void ExpandCategory(Category category, TreeViewItem treenode)
        {
            if (treenode.Items.Count == 0 && !category.IsMargin)
            {//展开
                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    List<Category> subcats = this.Mentor.GetSubCategories(category.NodeId);
                    this.Dispatcher.BeginInvoke(delegate
                    {
                        for (int i = 0; i < subcats.Count; i++)
                        {
                            Category subcategory = (Category)subcats[i];
                            this.ShowCategory(subcategory, treenode.Items);
                            treenode.IsExpanded = true;
                        }
                    });
                });
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="category"></param>
        public void ApplyCategory(Category category)
        {
            TreeViewItem treenode = null;
            if (this.CategoryTreeNodes.ContainsKey(category.NodeId))
            {
                treenode = this.CategoryTreeNodes[category.NodeId];
                this.SelectTreeViewItem(treenode);
            }
            else if (category.ParentId != 0 && this.CategoryTreeNodes.ContainsKey(category.ParentId))
            {
                TreeViewItem parenttreenode = this.CategoryTreeNodes[category.ParentId];
                ExpandCategory((Category)parenttreenode.Tag, parenttreenode);
                if (!this.CategoryTreeNodes.TryGetValue(category.NodeId, out treenode))
                    throw new Exception("Wrong!");
                this.SelectTreeViewItem(treenode);
            }
            else
            {//必须找到整个序列
                this.Mentor.GetCategroyHierarchy(category.NodeId);
            }
            //treenode.EnsureVisible();
            //this.SelectedItem = treenode;
        }
        void Mentor_GetCategroyHierarchyCompletedEvent(List<Category> categories)
        {
            ApplyCategoryHierarchy(categories, 0);
        }
        List<Category> Hierarchy;
        int CurrentIndex;
        TreeViewItem CurrentItem;
        void ApplyCategoryHierarchy(List<Category> hierarchy, int index)
        {
            this.Hierarchy = hierarchy;
            for(int i=hierarchy.Count-1;i>=0;i--)
            {
                TreeViewItem item;
                if(this.CategoryTreeNodes.TryGetValue(hierarchy[i].NodeId, out item))
                {
                    CurrentItem=item;
                    CurrentIndex=i;
                    item.IsExpanded = true;
                }
                else
                {
                    System.Threading.ThreadPool.QueueUserWorkItem(delegate{
                        List<Category> subcates = this.Mentor.GetSubCategories(hierarchy[CurrentIndex].NodeId);
                        this.Dispatcher.BeginInvoke(delegate{
                            this.OnHierarchySubCategories(subcates);
                        });
                    });
                    break;
                }
            }
        }

        void OnHierarchySubCategories(List<Category> subcates)
        {
            TreeViewItem deeper = null;
            foreach (Category cate in subcates)
            {
                TreeViewItem item = this.ShowCategory(cate, this.CurrentItem.Items);
                if(cate.NodeId==this.Hierarchy[this.CurrentIndex-1].NodeId)
                {
                    deeper = item;
                }
            }
            this.CurrentItem.IsExpanded = true;
            this.CurrentItem = deeper;
            this.CurrentIndex--;
            if (this.CurrentIndex == 0)
            {//终结本次递归
                SelectTreeViewItem(this.CurrentItem);
                this.CurrentIndex = -1;
                this.CurrentItem = null;
                this.Hierarchy = null;
                return;
            }
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                List<Category> deepersubcates = this.Mentor.GetSubCategories(this.Hierarchy[CurrentIndex].NodeId);
                this.Dispatcher.BeginInvoke(delegate
                {
                    this.OnHierarchySubCategories(deepersubcates);
                });
            });
        }

        void SelectTreeViewItem(TreeViewItem item)
        {
            if (this.SelectedItem != null)
            {
                ((TreeViewItem)this.SelectedItem).IsSelected = false;
            }
            item.IsSelected = true;
            this.SelectedTreeViewItem = item;
            this.SelectedCategory = (Category)item.Tag;
            this.SelectedCategoryChanged(this.SelectedCategory);
        }
    }
}
